﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FeatureModelTool.ProjectView;
using FeatureModelTool.Windows;
using FeatureModelTool.ProjectView.ProjectTreeStructures;
using TreeGraphicalControl;
using FeatureModelTool.ProjectView.TreeItems;
using WinForms = System.Windows.Forms;
using FeatureModelCore;
using FeatureModelTool.FeatureModelView;
using FeatureModelTool.FeatureModelView.TreeViewItems;
using FeatureModelCore.FMTypes;
using FeatureModelTool.FileView;
using FeatureModelTool.InformationBox;
using FeatureModelCore.FMInterface;

namespace FeatureModelTool
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ProjectTreeViewITemGenerator _projGenerator;


        public MainWindow()
        {
            InitializeComponent();

            // initialize project tree view
            _projGenerator = new ProjectTreeViewITemGenerator(TreeItem_ProjectTreeRoot.ConstructTreeItem
                , TreeItem_ProjectTreeRoot.ContextGenerator);
            // register folder
            ItemRegister folderRegister = new ItemRegister(typeof(ProjectFolder),
                typeof(TreeItem_ProjectFolder),
                TreeItem_ProjectFolder.ConstructTreeItem,
                TreeItem_ProjectFolder.ContextGenerator);
            _projGenerator.Register(folderRegister);
            // register file
            ItemRegister fileRegister = new ItemRegister(typeof(ProjectFile),
                typeof(TreeItem_ProjectFile),
                TreeItem_ProjectFile.ConstructTreeItem,
                TreeItem_ProjectFile.ContextGenerator);
            _projGenerator.Register(fileRegister);

            // bind generator
            this.projTreeView.BindGenerator(_projGenerator);

            //string folderPath = "C:\\ACM\\feature-model-tool\\";
            //string projName = "SampleProject";
            // just for test
            //ProjectTree projTree = new ProjectTree(folderPath, projName, true);
            //projTree.ProjectName = "Test";
            //this.projTreeView.Bind(projTree);
            // this.projectViewBox.Child = tr;

            //FeatureModelTree tree = GenerateFeatureModel();
            //this.Test.TreeView.Bind(tree);

            //TabItem tabItem = new TabItem();
            //tabItem.Content = tabItem;
        }

        #region Menu EventHandler
        /// <summary>
        /// New Project
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NewProjectMenuItem_Click(object sender, RoutedEventArgs e)
        {
            NewProjectDialog dialog = new NewProjectDialog();
            dialog.ShowDialog();

            if (dialog.Dirty == false)
            {
                return;
            }

            ProjectTree proj =  new ProjectTree(dialog.ProjectFolderPath
                , dialog.ProjectName, true);
            this.projTreeView.Bind(proj);
        }
        /// <summary>
        /// Open Project
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenProjectMenuItem_Click(object sender, RoutedEventArgs e)
        {
            WinForms.OpenFileDialog openDialog = new WinForms.OpenFileDialog();
            openDialog.Filter = "Project Files (.fmproj)|*.fmproj|All Files (*.*)|*.*";
            WinForms.DialogResult ret = openDialog.ShowDialog();
            if (ret == WinForms.DialogResult.OK)
            {
                ProjectTree projTree = ProjectTree.Load(openDialog.FileName);
                this.projTreeView.Bind(projTree);
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AboutMenuItem_Click(object sender, RoutedEventArgs e)
        {
            AboutDialog ab = new AboutDialog();
            ab.ShowDialog();
        }
        /// <summary>
        /// Save all files include save the project
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveAllMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // save project
            ProjectTree projTree = (ProjectTree)this.projTreeView.TreeInstance;
            projTree.Save();

            this.FileViewer.SaveAllFiles();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.FileViewer.SaveCurrentFile();
        }
        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
        #endregion

        #region Static Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static MainWindow GetCurrentWindowsInstance(DependencyObject control)
        {
            Window win = GetWindow(control);
            MainWindow mainWin = win as MainWindow;
            return mainWin;
        }
        /// <summary>
        /// Load Icon
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <returns></returns>
        public static Image LoadIcon(string sourcePath)
        {
            Image icon = new Image();
            icon.Margin = new Thickness(0, 0, 10, 0);
            icon.Height = 15;
            icon.Stretch = Stretch.Fill;
            BitmapImage myBitmapImage = new BitmapImage();
            // BitmapImage.UriSource must be in a BeginInit/EndInit block
            myBitmapImage.BeginInit();
            myBitmapImage.UriSource = new Uri(sourcePath, UriKind.Relative);
            myBitmapImage.EndInit();
            icon.Source = myBitmapImage;


            return icon;
        }

        /// <summary>
        /// Generate Tree Item Header
        /// </summary>
        /// <param name="iconUri"></param>
        /// <returns></returns>
        public static DockPanel GenerateTreeItemHeader(string headerText, string iconUri, Brush color)
        {
            Image icon = MainWindow.LoadIcon(iconUri);

            //this.Header = icon;
            DockPanel solutionHeader = new DockPanel();
            solutionHeader.Height = 20;

            TextBlock tb = new TextBlock();
            tb.VerticalAlignment = VerticalAlignment.Center;
            tb.Text = headerText;
            tb.Margin = new Thickness(0, 0, 12, 0);
            tb.Foreground = Brushes.Black;
            

            //solutionHeader.Background = color;
            solutionHeader.Children.Add(icon);
            solutionHeader.Children.Add(tb);

            return solutionHeader;
        }

        #endregion

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.FileViewer.IsDirty() == false
                && (this.projTreeView.TreeInstance == null 
                || this.projTreeView.TreeInstance.Dirty == false))
            {
                return;
            }


            ClosingWarningDialog dia = new ClosingWarningDialog();
            dia.ShowDialog();

            if (dia.ToSave == true)
            {
                SaveAllMenuItem_Click(null, null);
            }

            if (dia.ToClose == false)
            {
                e.Cancel = true;
            }
        }
        /// <summary>
        /// Resize
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            const int MENU_HEIGHT = 20;
            const int INFO_HEIGHT = 150;

            MainWindow mainWindows = sender as MainWindow;
            //mainWindows.Width = mainWindows.ActualWidth;
            //mainWindows.Height = mainWindows.MaxHeight;

            double winWidth = mainWindows.mainGrid.ActualWidth;
            double winHeight = mainWindows.mainGrid.ActualHeight;
            // resize dock panel
            //mainWindows.AppPanel.Width = winWidth;
            //mainWindows.AppPanel.Height = winHeight;

            // resize menu bar
            mainWindows.menu.Width = winWidth;
            mainWindows.menu.Height = MENU_HEIGHT;

            //// resize project View bar
            this.ProjectViewBorder.Height = winHeight - MENU_HEIGHT - INFO_HEIGHT - 5;
            //this.ProjectViewGrid.Width = 200;

            // resize file viewer
            this.FileViewBorder.Height = winHeight - MENU_HEIGHT - INFO_HEIGHT - 5;
            this.FileViewer.Height = winHeight - MENU_HEIGHT - INFO_HEIGHT - 5;

            // resize info
            this.InformationBorder.Width = winWidth;
            this.InfomationGrid.Width = winWidth;
            this.InformationBox.Width = winWidth;
            foreach (TabItem tabItem in InformationBox.Items)
            {
                if (tabItem is PropertyTab)
                {
                    PropertyTab pTab = (PropertyTab)tabItem;
                    pTab.TabItem_SizeChanged();
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void InformationBox_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            foreach (TabItem tabItem in InformationBox.Items)
            {
                if (tabItem is PropertyTab)
                {
                    PropertyTab pTab = (PropertyTab)tabItem;
                    pTab.TabItem_SizeChanged();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        public void SetPropertyInfo(IFeature node)
        {
            this.PropertyTab.Bind(node);
        }
    }
}
